package com.yctan.base.aop;

import com.alibaba.fastjson.JSONObject;
import com.yctan.base.entity.RestLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author sec
 * @create 2020-07-16 18:04
 **/
@Aspect
@Component
@Slf4j
public class RestLogAspect {


    private RestLog restLog = null;

    /**
     * 定义切面，只置入带 @RestLog 注解的方法或类
     */
    @Pointcut("@annotation(com.yctan.base.annotation.RestLog)")
    public void pointcut() {

    }


    /**
     * 后置通知(在方法执行之后并返回数据) 用于拦截无异常的操作
     * @param joinPoint 切点
     */
    @Before("pointcut()")
    public void deBefore(JoinPoint joinPoint){

        try {
            //获取方法名
            String methodName = joinPoint.getSignature().getName();
            //获取目标类名
            String targetName = joinPoint.getTarget().getClass().getName();
            //获取相关参数
            Object[] arguments = joinPoint.getArgs();
            //生成类对象
            Class targetClass = Class.forName(targetName);

            if(arguments.length > 0){
                log.info("请求参数 : {}", JSONObject.toJSON(joinPoint.getArgs()) );
            }else{
                log.info("请求开始：没获取到请求参数");
            }

            Method[] methods = targetClass.getMethods();
            for(Method method : methods) {
                if(!method.getName().equals(methodName)) {
                    continue;
                }
                Class[] clazzs = method.getParameterTypes();
                if(clazzs.length != arguments.length) {
                //比较方法中参数个数与从切点中获取的参数个数是否相同，原因是方法可以重载
                    continue;
                }
                String url = (String) arguments[0];
                String param = (String) arguments[3];
                String header = (String) arguments[4];
                restLog = new RestLog();

            }

        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    @AfterReturning(returning = "ret", pointcut = "pointcut()")
    public void doAfterReturning(Object ret) throws Throwable {
        log.info(": 方法的返回值 : " + ret);
//        if(!ObjectUtils.isEmpty(ret)){
//            restLog.setResult(ret.toString());
//
//        }
//        restLogMapper.insert(restLog);
        log.info("记录请求日志成功");
    }

}

